package logic

import (
	"callsips/internal/fscurl/xmlcurl"
	"callsips/internal/model/account/asips"
	"callsips/internal/model/customer/cgateway"
	"callsips/internal/model/customer/risk"
	"callsips/internal/model/sips/cserver"
	"callsips/internal/model/sips/gateway"
	"callsips/internal/model/yunhu/accounttaocan"
	"callsips/internal/model/yunhu/mobile"
	"callsips/internal/model/yunhu/mobilebind"
	"context"
	"errors"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"time"

	"callsips/internal/svc"
	"github.com/zeromicro/go-zero/core/logx"
)

type FscurlLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 总控制
func (l *FscurlLogic) FsCurl(req map[string]string) (resp []byte, err error) {
	if req["section"] == "directory" {
		return l.directory(req)
	} else if req["section"] == "dialplan" {
		return l.dialplan(req)
	} else if req["section"] == "configuration" {
		return xmlcurl.NotFound(req), errors.New("总控制错误")
	}

	return xmlcurl.NotFound(req), errors.New("总控制错误")
}

// 用户
func (l *FscurlLogic) directory(post map[string]string) (resp []byte, err error) {
	// logx.Info(post)
	logx.Infof("获取用户：%s,类型：%s,动作:%s,内外部：%s,请求IP：%s,用户:d%", post["section"], post["action"], post["purpose"], post["profile"], post["sip_contact_host"], post["user"])

	if post["purpose"] == "gateways" {
		return l.gatewayList(post)
	} else if post["purpose"] == "network-list" {
		return l.networkListAc(post)
	} else if post["user"] != "" {
		return l.directoryReg(post)
	} else if post["group"] != "" {

	}

	return xmlcurl.NotFound(post), errors.New("总控制错误")
}

// 用户注册信息
func (l *FscurlLogic) directoryReg(post map[string]string) (resp []byte, err error) {
	logx.Infof("用户注册信息:domain=%s,user=%s", post["domain"], post["user"])
	if post["domain"] == "" || post["user"] == "" {
		return xmlcurl.NotFound(post), nil
	}

	//增加测试用户
	if post["user"] == fmt.Sprintf("%d", l.svcCtx.Config.SipText.DestNumber) {
		document := xmlcurl.NewDocument()
		section := xmlcurl.NewSection("directory")
		section.Attrdescription = "FreeSWITCH Directory"
		section.Domain = xmlcurl.XMLDomainDirectoryTextUser()
		document.AddSection(section)
		return xmlcurl.PrepareDocument(document), nil
	}

	var (
		asipInfo    *asips.AccountAsips
		gateWayInfo *cgateway.CustomerCgateway
		cserverInfo *cserver.SipsCserver
		bindInfo    *mobilebind.YunhuMobileBind
		phoneInfo   *mobile.YunhuMobile
	)

	//查询用户
	if asipInfo, err = l.svcCtx.AccountSips.FindOneByUsername(l.ctx, post["user"]); err != nil {
		logx.Infof("查询SIP用户名为:%s,错误信息为:%s", post["user"], err.Error())
		return xmlcurl.NotFound(post), nil
	}

	//查询企业sip
	if gateWayInfo, err = l.svcCtx.CustomerGateway.FindOneByCustomerId(l.ctx, asipInfo.CustomerId); err != nil {
		logx.Infof("查询sip用户名所属企业网关为:%s,企业ID：%d，座席ID:%d,错误信息为:%s", post["user"], asipInfo.CustomerId, asipInfo.AccountId, err.Error())
		return xmlcurl.NotFound(post), nil
	}

	//查询服务器
	if cserverInfo, err = l.svcCtx.SipCserver.FindOne(l.ctx, gateWayInfo.ServerId); err != nil {
		logx.Infof("查询sip用户名所属企业网关为:%s,企业ID：%d，座席ID:%d,服务器ID:%d,错误信息为:%s", post["user"], asipInfo.CustomerId, asipInfo.AccountId, gateWayInfo.ServerId, err.Error())
		return xmlcurl.NotFound(post), nil
	}

	//查询绑定的号码
	if bindInfo, err = l.svcCtx.YunhuMobileBind.FindOneByCustomerIdAccountId(l.ctx, asipInfo.CustomerId, asipInfo.AccountId); err != nil {
		logx.Infof("查询sip用户名绑定的号码Id:%s,企业ID：%d，座席ID:%d,错误信息为:%s", post["user"], asipInfo.CustomerId, asipInfo.AccountId, err.Error())
		return xmlcurl.NotFound(post), nil
	}

	if phoneInfo, err = l.svcCtx.YunhuMobile.FindOne(l.ctx, bindInfo.PhoneId); err != nil {
		logx.Infof("查询sip用户名绑定的号码:%s,企业ID：%d，座席ID:%d,错误信息为:%s", post["user"], asipInfo.CustomerId, asipInfo.AccountId, err.Error())
		return xmlcurl.NotFound(post), nil
	}

	document := xmlcurl.NewDocument()
	section := xmlcurl.NewSection("directory")
	section.Attrdescription = "FreeSWITCH Directory"
	section.Domain = xmlcurl.XMLDomainDirectoryUser(asipInfo, phoneInfo, cserverInfo)
	document.AddSection(section)
	return xmlcurl.PrepareDocument(document), nil
}

// 服务器允许
func (l *FscurlLogic) networkListAc(post map[string]string) (resp []byte, err error) {
	document := xmlcurl.NewDocument()
	section := xmlcurl.NewSection("configuration")
	section.Attrdescription = "config-acl"
	section.Configuration = xmlcurl.XMLDomainNetworkListAcl()
	document.AddSection(section)
	return xmlcurl.PrepareDocument(document), nil
}

// 网关
func (l *FscurlLogic) gatewayList(post map[string]string) (resp []byte, err error) {

	return xmlcurl.NotFound(post), nil

	//var (
	//	gateWayList []*gateway.SipsGateway
	//	cserverList []*cserver.SipsCserver
	//)
	//
	//if gateWayList, err = l.svcCtx.SipGateway.List(l.ctx, "", 1, 1, 200); err != nil {
	//	return xmlcurl.NotFound(post), nil
	//}
	//
	////查询服务器
	//if cserverList, err = l.svcCtx.SipCserver.List(l.ctx, "", 1, 1, 200); err != nil {
	//	return xmlcurl.NotFound(post), nil
	//}
	//
	//document := xmlcurl.NewDocument()
	//section := xmlcurl.NewSection("directory")
	//section.Attrdescription = "Gateway directory"
	//section.Domain = xmlcurl.XMLGatewayList(cserverList, gateWayList)
	//document.AddSection(section)
	//return xmlcurl.PrepareDocument(document), nil
}

// 拨号计划
func (l *FscurlLogic) dialplan(post map[string]string) (resp []byte, err error) {
	contextName, ok := post["Caller-Context"]
	if !ok {
		return xmlcurl.NotFound(post), nil
	}

	accountId, ok := post["Caller-Caller-ID-Number"]

	if !ok {
		return xmlcurl.NotFound(post), nil
	}

	//被叫
	destinationNumber, ok := post["Caller-Destination-Number"]

	if !ok {
		return xmlcurl.NotFound(post), nil
	}

	var (
		asipInfo        *asips.AccountAsips
		customerGateWay *cgateway.CustomerCgateway
		sipsGateway     *gateway.SipsGateway
		customerRisk    *risk.CustomerRisk
		accountTaocan   *accounttaocan.YunhuAccountTaocan
	)

	if asipInfo, err = l.svcCtx.AccountSips.FindOneByUsername(l.ctx, accountId); err != nil {
		logx.Infof("查询AccountSips信息错误：%s", err.Error())
		return xmlcurl.NotFound(post), nil
	}

	if customerGateWay, err = l.svcCtx.CustomerGateway.FindOneByCustomerId(l.ctx, asipInfo.CustomerId); err != nil {
		logx.Infof("查询customerGateWay信息错误：%s", err.Error())
		return xmlcurl.NotFound(post), nil
	}

	if customerRisk, err = l.svcCtx.CustomerRisk.FindOneByCustomerId(l.ctx, asipInfo.CustomerId); err != nil {
		logx.Infof("查询CustomerRisk信息错误：%s", err.Error())
		return xmlcurl.NotFound(post), nil
	}

	if asipInfo.GatewayId > 0 {
		if sipsGateway, err = l.svcCtx.SipGateway.FindOne(l.ctx, asipInfo.GatewayId); err != nil {
			logx.Infof("查询SipGateway account信息错误：%s", err.Error())
			return xmlcurl.NotFound(post), nil
		}
	} else {
		if sipsGateway, err = l.svcCtx.SipGateway.FindOne(l.ctx, customerGateWay.GatewayId); err != nil {
			logx.Infof("查询SipGateway信息错误：%s", err.Error())
			return xmlcurl.NotFound(post), nil
		}
	}

	// 获取套餐信息
	var monthUse string = time.Now().Local().Format("2006-01")
	if accountTaocan, err = l.svcCtx.AccountTaocan.FindOneByCustomerIdAccountIdMonthUseKind(l.ctx, asipInfo.CustomerId, asipInfo.AccountId, monthUse, sipsGateway.Kind); err != nil && err != sqlx.ErrNotFound {
		logx.Infof("查询accountTaocan信息错误：%s", err.Error())
		return xmlcurl.NotFound(post), nil
	}

	var destNumber string = fmt.Sprintf("%d", l.svcCtx.Config.SipText.DestNumber)
	if destNumber != "" && destNumber == destinationNumber {
		document := xmlcurl.NewDocument()
		section := xmlcurl.NewSection("dialplan")
		section.Attrdescription = "FreeSWITCH Dialplan"
		section.Context = xmlcurl.XMLDialplanTextContext(destinationNumber, destNumber, contextName, accountTaocan)
		document.AddSection(section)
		return xmlcurl.PrepareDocument(document), nil
	}

	document := xmlcurl.NewDocument()

	section := xmlcurl.NewSection("dialplan")
	section.Attrdescription = "FreeSWITCH Dialplan"
	section.Context = xmlcurl.XMLDialplanContext(destinationNumber, contextName, customerRisk, sipsGateway, customerGateWay, accountTaocan)
	document.AddSection(section)
	return xmlcurl.PrepareDocument(document), nil
}

func NewCallsipsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FscurlLogic {
	return &FscurlLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}
